lume = require 'lib.lume'
sock = require 'lib.sock'
bitser = require 'lib.bitser'
tick = require 'lib.tick'

lg = love.graphics
lk = love.keyboard


function Reshuffle()
  local maxd = 50
	x = love.math.random(b.l,b.r)
	y = love.math.random(b.u,b.b)
  if (x < 50 and x > -50) or (y < 50 and y > -50) then
      x,y = Reshuffle()
  end
  return x,y
end

function newTrap()
  local rx,ry = Reshuffle()
  return {
    x = rx,
    y = ry,
    --i = lg.newImage("trap.png"),
    }
end


function newPresent()
  local rx,ry = Reshuffle()
  return {
    x = rx,
    y = ry,
	  --i = lg.newImage("present.png"),
	  w = 50,
	  h = 50,
    r = .5 + .5 * math.random(),
    g = .5 + .5 * math.random(),
    b = .5 + .5 * math.random(),
    }
end

function newRabbit()
  local rx,ry = Reshuffle()
  return {
    x = rx,
    y = ry,
    nx= rx,
    ny= ry,
    ms= 350 ,-- max speed
    s = 0 ,-- speed
    p = 0 ,-- power
    a = 3 ,--acceleration
    rt= 0 ,--rotation
    --r = 0 g = 0 b =
    --i = lg.newImage("rabbit.png"),
    j = false ,--jumped
    score = 0,
    presents = {},
    nickname = "wtf,no nicknam??"
    }
end

function love.load()
  --defining global values
  b = { --borders
    u = -1000,
    b = 1000,
    l = -1000,
    r = 1000,
  }
  lg.setDefaultFilter("nearest","nearest")
  presents = {}
  traps = {}
  players = {}
  local maxpres = 50
  for i=1, maxpres do
    local p = newPresent()
    table.insert(presents,p)
  end
  timer = tick.recur( function()
    if trapt == 0 then reTraps() end
      trapt = trapt-1
    end, 1)
  -- server stuff 
  tckRate = 1/60
  tck = 0

  server = sock.newServer("*", 42056, 25)
  server:setSerialization(bitser.dumps, bitser.loads)
  print("server initialized succsefully!")

  reTraps()

  server:on("connect",function(data,client)
    if #server.clients > 25 then client:send("tooManyPlayers") return end
      local r = newRabbit()
      local id = #players + 1
      table.insert(players,r)
      client:send("playerNum",id)
      client:send("trapState",traps)
      client:send("presentState",presents)
      print("connected client #"..id.."!")
    end
  )
  server:setSchema("setName",{"id","name"})
  server:on("setName",function(d)
    players[d.id].nickname = d.name
    server:sendToAll("playerConnected",{d.id,players})
  end
)

  
  server:on("pred",function(d,client)
    table.remove(players,d)
      server:sendToAll("playerLeft",d)
      client:send("quit")
      client:disconnectNow()
      end
  )
  server:on("disconnect",function(data,client)
  end
)


  server:setSchema("playerUpdate",{
    "id",
    "x",
    "y",
    "ppr",
    "score"
  })
  server:on("playerUpdate", function(d,client)
    local p = players[d.id]
    if p == nil then return end
    p.x = d.x
    p.y = d.y
    p.presents = d.ppr
    p.score = d.score
    server:sendToAll("playerState",{d.id,d.x,d.y,p.presents,d.score})
  end     
  )  

  server:on("playerCollided", function(p,client)
    if p~= presents then
      presents = p
      server:sendToAll("presentState",presents)
    end
  end
  )

  server:setSchema("rotatePlayer",{
    "id",
    "a"
  })
  server:on("rotatePlayer", function(d,client)
    if players[d.id] == nil then return end
    players[d.id].rt = d.a
    server:sendToAll("rotatePlayer",{d.id,d.a})
    end
  )

end

function reTraps()
  traps = {}
  trapt = 30
  for i=1, 30 do
    local t = newTrap()
    table.insert(traps,t)
  end
    server:sendToAll("trapState",t)
end

function love.update(dt)
  tick.update(dt)
  server:update()
  
  tck = tck + dt

  if tck >= tckRate then
      tck = 0
      for i, player in pairs(players) do
          server:sendToAll("playerState", {i, player.x,player.y,player.presents,player.score})
      end
      server:sendToAll("trapState",traps)
  end
end
